package com.hunan.api.catv.service.biz.collect;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.hunan.api.catv.common.ConstantsMsg;
import com.hunan.api.catv.entity.ServiceResult;
import com.hunan.api.catv.entity.dto.MemberTryWatchLiveRuleDto;
import com.hunan.api.catv.entity.enums.ColumnEnum;
import com.hunan.api.catv.entity.po.Collect;
import com.hunan.api.catv.entity.po.MemberRight;
import com.hunan.api.catv.entity.vo.AlbumVo;
import com.hunan.api.catv.entity.vo.CollectVo;
import com.hunan.api.catv.entity.vo.LiveVo;
import com.hunan.api.catv.entity.vo.NewsVo;
import com.hunan.api.catv.mq.MqConstants;
import com.hunan.api.catv.service.ResultService;
import com.hunan.api.catv.service.biz.cache.CacheBiz;
import com.hunan.api.catv.service.biz.mq.MqBiz;
import com.hunan.api.catv.service.biz.news.NewsBiz;
import com.hunan.api.catv.service.biz.system.SystemDictBiz;
import com.hunan.api.catv.service.impl.collect.CollectService;
import com.hunan.api.catv.utils.GsonUtils;
import com.hunan.api.catv.utils.RedisUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;

@Service
public class CollectBiz extends ResultService {

    @Autowired
    CollectService collectService;

    @Autowired
    AmqpTemplate amqpTemplate;

    @Autowired
    CollectBiz collectBiz;

    @Autowired
    NewsBiz newsBiz;

    @Autowired
    CacheBiz cacheBiz;

    @Autowired
    MqBiz mqBiz;
    @Autowired
    private SystemDictBiz systemDictBiz;

    @Autowired
    private RedisUtils redisUtils;

    private static final String DEFAULT_RIGHT_CODE = "R000000";
    private static final Integer NORMAL_STATE = 1;
    private static final Integer NOT_DELETED = 1;
    private static final String MEMBER_TRY_WATCH_RULE = "member_try_watch_rule";

    public ServiceResult submit(Integer memberId, String itemId, Integer contentType, Integer collectType) {
        JsonObject msg = new JsonObject();
        msg.addProperty("itemId", itemId);
        msg.addProperty("memberId", memberId);
        msg.addProperty("contentType", contentType);
        msg.addProperty("collectType", collectType);
        ServiceResult result = mqBiz.push(MqConstants.collect_exchange, MqConstants.collect_routingkey, msg.toString());
        if (!result.getStatus()) {
            return buildFail(false, ConstantsMsg.collect_add_fail);
        }
        return buildOK(result.getData(), collectType == 1 ? "收藏成功" : "取消收藏成功");
    }

    public ServiceResult add(Integer memberId, String itemId, Integer contentType) {
        boolean flag = collectBiz.status(memberId, Integer.valueOf(itemId), contentType);
        if (!flag) {
            Collect collect = new Collect();
            collect.setMemberId(memberId);
            collect.setItemId(Integer.valueOf(itemId));
            collect.setContentType(contentType);
            ServiceResult result = collectService.add(collect);
            if (result.getStatus()) {
                return result;
            }
        }
        return buildFail(false, ConstantsMsg.collect_add_fail);
    }

    public ServiceResult delete(Integer memberId, String itemId, Integer contentType) {
        Collect memberCollect = new Collect();
        memberCollect.setMemberId(memberId);
        memberCollect.setContentType(contentType);
        JsonArray itemIdArr = GsonUtils.fromJson(itemId, JsonArray.class);
        for (JsonElement id : itemIdArr) {
            memberCollect.setItemId(id.getAsInt());
            ServiceResult result = collectService.batchDelete(memberCollect);
            if (!result.getStatus()) {
                return buildFail(false, ConstantsMsg.collect_del_fail);
            }
        }
        return buildOK(true, ConstantsMsg.admin_del_success);
    }

    public PageInfo<CollectVo> list(Integer pageNum, Integer pageSize, Integer memberId, Integer contentType) {
        PageHelper.startPage(pageNum, pageSize);
        Collect collect = new Collect();
        collect.setMemberId(memberId);
        collect.setContentType(contentType);
        List<CollectVo> list = collectService.list(collect);
        Iterator<CollectVo> it = list.iterator();
        while (it.hasNext()) {
            CollectVo cVo = it.next();
            Integer itemId = cVo.getItemId();
            if (contentType.equals(ColumnEnum.news.getCode())) {
                NewsVo news = cacheBiz.newsInfo(itemId);
                if (!ObjectUtils.isEmpty(news) && 1 == news.getState()) {
                    cVo.setContent(news);
                } else {
                    it.remove();
                }
            }

            if (contentType.equals(ColumnEnum.tv.getCode())) {
                LiveVo live = cacheBiz.liveInfo(itemId);
                if (!ObjectUtils.isEmpty(live)) {
                    MemberTryWatchLiveRuleDto memberTryWatchRuleDto = JSONUtil.toBean(systemDictBiz.getStringByKey(MEMBER_TRY_WATCH_RULE), MemberTryWatchLiveRuleDto.class);
                    if (memberTryWatchRuleDto != null) {
                        Boolean globalTryWatchSwitch = Boolean.valueOf(Optional.ofNullable(memberTryWatchRuleDto.getGlobalTryWatchSwitch()).orElse("false"));
                        if (globalTryWatchSwitch) {
                            String beginTimeEndTime = (String) redisUtils.hget("member_try_watch_key", "member" + memberId);
                            MemberRight memberRight = null;
                            LocalDateTime beginTime = null;
                            LocalDateTime endTime = null;
                            if (beginTimeEndTime != null) {
                                String[] split = beginTimeEndTime.split("-");
                                beginTime = LocalDateTime.parse(split[0], DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
                                endTime = LocalDateTime.parse(split[1], DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
                            } else {
                                memberRight = new MemberRight().selectOne(new QueryWrapper<MemberRight>().
                                        eq(MemberRight.MEMBER_ID, memberId).
                                        eq(MemberRight.RIGHT_CODE, DEFAULT_RIGHT_CODE).
                                        eq(MemberRight.STATE, NORMAL_STATE).
                                        eq(MemberRight.DELETED, NOT_DELETED));
                            }
                            if (beginTime == null && endTime == null && memberRight != null) {
                                beginTime = LocalDateTime.ofInstant(memberRight.getBeginTime().toInstant(), ZoneId.systemDefault());
                                endTime = LocalDateTime.ofInstant(memberRight.getEndTime().toInstant(), ZoneId.systemDefault());
                                if (beginTime != null && endTime != null) {
                                    redisUtils.hset("member_try_watch_key", "member" + memberId, beginTime.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + "-" + endTime.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
                                }
                            }
                            if (beginTime != null && endTime != null) {
                                LocalDateTime now = LocalDateTime.now();
                                if (now.compareTo(beginTime) >= 0 && now.compareTo(endTime) <= 0) {
                                    live.setNeedsBind(false);
                                } else {
                                    live.setNeedsBind(true);
                                }
                            }
                        }
                    }
                    cVo.setContent(live);
                } else {
                    it.remove();
                }
            } else if (contentType.equals(ColumnEnum.tv.getCode()) || contentType.equals(ColumnEnum.live.getCode())) {
                LiveVo live = cacheBiz.liveInfo(itemId);
                if (!ObjectUtils.isEmpty(live) && 1 == live.getState()) {
                    cVo.setContent(live);
                } else {
                    it.remove();
                }
            }

            if (contentType.equals(ColumnEnum.video.getCode())) {
                AlbumVo album = cacheBiz.albumInfo(itemId);
                if (!ObjectUtils.isEmpty(album) && 1 == album.getState()) {
                    cVo.setContent(album);
                } else {
                    it.remove();
                }
            }
        }
        PageInfo<CollectVo> contentPage = new PageInfo<CollectVo>(list);
        return contentPage;
    }

    public boolean status(Integer memberId, Integer itemId, Integer contentType) {
        Collect collect = new Collect();
        collect.setMemberId(memberId);
        collect.setItemId(itemId);
        collect.setContentType(contentType);
        Integer count = collectService.count(collect);
        return count > 0 ? true : false;
    }
}
